﻿<template>
    <el-select v-model="val" @visible-change="onVisibleChange">
        <el-option v-if="allowEmpty" :label="'-' + title + '-'" value=""></el-option>
        <el-option v-for="item in items" :label="item.label" :value="item.value" :key="item.value"></el-option>
    </el-select>
</template>

<script>
import { watch, toRef } from 'vue';
export default {
    name: "MySelect",
    emits: ["update:modelValue"],
    props: {
        modelValue: [String, Number],
        title: String,
        cfg: {
            type: Object,
            default() {
                return {}
            }
        },
        formData: Object,
        pformSearch: Object, //父亲form传来的过滤条件//跟随formData一起变化
        tbname: String,
        allowEmpty: {
            type: Boolean,
            default: false,
        },
        options: Array,
    },
    created() {
        this.proceParenFormSearch();
        this.val = this.getValue2(this.modelValue);
    },
    data() {
        return {
            val: undefined,
            action: "",
            items: [],
            records: [],
            watchStop: null,
            servercall: null,
        };
    },
    methods: {
        loadData() {
            var valueField = this.cfg.valueField || "ID";
            var labelField = this.cfg.labelField || "Name";

            let moduleName = this.cfg.tbname || this.tbname;
            //防止多次加载同样的数据， created时候，formData变化的时候都会触发， 但是检索条件一致， 只需要触发一次即可
            if (moduleName && this._lastSearch != JSON.stringify(this.cfg)) {
                this._lastSearch = JSON.stringify(this.cfg);

                let pm = { ...this.cfg.search, _cache: false };

                this.servercall = this.$server.list(moduleName, 1, 1000, pm, this.$el).then((res) => {
                    var lst = [];
                    var records = res.records || res;
                    for (var ix = 0; ix < records.length; ix++) {
                        var record = records[ix];
                        var item = {
                            value: record[valueField],
                            label: record[labelField],
                            record: record,
                        };
                        lst.push(item);
                    }
                    this.records = records;
                    this.items = lst;
                    //this.setOtherFields(this.modelValue);
                });
            } else if (this.cfg.options) {
                this.records = this.cfg.options;
                this.items = this.cfg.options;
            } else if (this.options) {
                this.records = this.options;
                this.items = this.options;
            }
        },
        proceParenFormSearch() {
            if (this.pformSearch && this.formData) {
                let nSearch = {};
                let wws = [];
                Object.keys(this.pformSearch).map((p) => {
                    let v = this.pformSearch[p];
                    if (v) {
                        let vv = toRef(this.formData, v);
                        nSearch[p] = vv.value;
                        wws.push(vv);
                    }
                });
                if (this.watchStop) {
                    this.watchStop();
                }
                this.watchStop = watch(wws, () => {
                    this.loadData();
                    this.val = "";
                })

                nSearch = { ...this.cfg.search, ...nSearch };

                this.cfg.search = nSearch;

                this.loadData();
            } else {
                this.loadData();
            }
        },
        onVisibleChange(val) {
            if (val && this.pformSearch && this.formData) {
                //值被清空的时候检查，是否上级过滤条件已变，适时重新加载过滤后数据
                let nSearch = {};
                Object.keys(this.pformSearch).map((p) => {
                    let v = this.pformSearch[p];
                    if (v) {
                        nSearch[p] = this.formData[v];
                    }
                });
                const cPSearch = JSON.stringify(nSearch);
                if (cPSearch != this.oldPSearch) {
                    this.proceParenFormSearch();
                }
            }
        },
        setOtherFields(newVal) {
            //关联更新的时候， 比如选择了新的班级以后，清空学生姓名，否则可能出现学生不属于这个班级的情况
            //还有一种情况，加载数据的时候，把记录上原本的学生姓名给情况了
            //此时要判断如果是同一个学校，不需要执行其它字段的关联更新
            if(newVal==this.modelValue)return;
            if (this.cfg.srcFields && this.cfg.destFields && this.formData) {
                let moduleName = this.cfg.tbname || this.tbname;

                var valueField = this.cfg.valueField || (moduleName ? "ID" : "value");
                var labelField = this.cfg.labelField || (moduleName ? "Name" : "label");


                let item = this.records.filter((p) => p[valueField] == newVal)[0];
                if (!item) return;

                let src = this.cfg.srcFields.split(",");
                let dst = this.cfg.destFields.split(",");

                let oldIx = src.indexOf(labelField);
                if (oldIx != -1) {
                    let oldVal = this.formData[dst[oldIx]];
                    if (item[src[oldIx]] == oldVal) return;
                }
                for (let ix = 0; ix < src.length; ix++) {
                    let pkey = dst[ix];
                    this.formData[pkey] = item[src[ix]];
                }
            }
        },

        getValue2(val) {
            let n = Number(val);
            let newVal = val;
            if (val && !isNaN(n)) {
                newVal = parseInt(val);
            }
            return newVal;
        }
    },
    watch: {
        cfg() {
            this.proceParenFormSearch();
        },

        pformSearch() {
            this.proceParenFormSearch();
        },
        formData() {
            this.proceParenFormSearch();
        },
        modelValue(newValue) {
            this.val = this.getValue2(newValue);
        },
        options() {
            this.items = this.options;
        },
        val(newValue) {
            this.setOtherFields(newValue);
            this.$emit("update:modelValue", newValue);
        },
    },
};
</script>